/**
 * 版权所有(C)，上海勾芒信息科技，2017，所有权利保留。
 * 
 * 项目名：	cards-web
 * 文件名：	WxAppConfigStorageImpl.java
 * 模块说明：	
 * 修改历史：
 * 2017年4月13日 - Debenson - 创建。
 */
package com.alex.wechat.app.config;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.alex.wechat.app.account.entity.WxAppAccountEntity;
import com.alex.wechat.app.account.service.WxAppAccountServiceI;

import cn.binarywang.wx.miniapp.api.WxMaConfigEx;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;

/**
 * @author Debenson
 * @since 0.1
 */
public class WxMaDbConfigStorage implements WxMaConfigEx {

  @Autowired
  private WxAppAccountServiceI accountService;
  /**
   * 微信通用TOKEN
   */
  @Value("${wx.token}")
  private String token;
  /**
   * 网站域名
   */
  @Value("${domain}")
  private String webBaseUrl;
  private Lock accessTokenLock = new ReentrantLock();

  protected WxAppAccountEntity ensureAccount() {
    WxAppAccountEntity account = WxAppContext.getAppAccount();
    if (account == null) {
      throw new RuntimeException("没有配置当前小程序账户");
    }
    return account;
  }

  @Override
  public String getAppid() {
    return ensureAccount().getAppId();
  }

  @Override
  public String getSecret() {
    return ensureAccount().getSecret();
  }

  @Override
  public String getToken() {
    return token;
  }

  @Override
  public String getAesKey() {
    return ensureAccount().getAesKey();
  }

  @Override
  public boolean isAccessTokenExpired() {
    WxAppAccountEntity account = ensureAccount();
    long expiresTime = (account.getExpiresTime() == null
        || StringUtils.isBlank(account.getAccesstoken())) ? 0 : account.getExpiresTime();
    return System.currentTimeMillis() > expiresTime;
  }

  @Override
  public void expireAccessToken() {
    WxAppAccountEntity account = ensureAccount();
    account.setExpiresTime(0L);
    try {
      accountService.saveOrUpdate(account);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public void updateAccessToken(WxAccessToken accessToken) {
    updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
  }

  @Override
  public void updateAccessToken(String accessToken, int expiresInSeconds) {
    WxAppAccountEntity account = ensureAccount();
    account.setAccesstoken(accessToken);
    long expiresIn = 0L;
    if (StringUtils.isNotBlank(accessToken)) {
      expiresIn = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
    }
    account.setExpiresTime(expiresIn);

    try {
      accountService.saveOrUpdate(account);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public String getAccessToken() {
    WxAppAccountEntity account = ensureAccount();
    return account.getAccesstoken();
  }

  @Override
  public Lock getAccessTokenLock() {
    return accessTokenLock;
  }

  @Override
  public String getPayMchId() {
    return ensureAccount().getPayMchId();
  }

  @Override
  public String getPayMchKey() {
    return ensureAccount().getPayMchKey();
  }

  @Override
  public String getPayNotifyUrl() {
    // 微信支付回调不支持https
    String payBaseUrl = webBaseUrl.replaceFirst("https:", "http:");
    return payBaseUrl + "/wxPaymentController/payCallback.do";
  }

  @Override
  public String getMsgDataFormat() {
    return WxMaConstants.MsgDataFormat.XML;
  }

  @Override
  public long getExpiresTime() {
    return ensureAccount().getExpiresTime();
  }

  @Override
  public String getHttpProxyHost() {
    return null;
  }

  @Override
  public int getHttpProxyPort() {
    return 0;
  }

  @Override
  public String getHttpProxyUsername() {
    return null;
  }

  @Override
  public String getHttpProxyPassword() {
    return null;
  }

  @Override
  public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
    return null;
  }

  @Override
  public boolean autoRefreshToken() {
    return true;
  }

}
